﻿import java.awt.*;
import java.io.*;
import java.sql.*;
import java.util.*;
import javax.swing.*;
// 房间管理
public class RoomManagement {
	public static JPanel HousingRegistration = null;
	// 记录第一个发现的空房间ID，其它模块要用到
	public static int firstEmptyRoomID = -1;
	/// 更新房间列表数据
	public static void UpdateRoomData() {
		firstEmptyRoomID = -1;// 重置第一个空房间ID为-1，表示未找到
		try{
			// 更新用户组数据
			Statement stmt = Main.conn.createStatement();// 创建执行SQL的对象
			ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM `HotelSysteam`.Room;");// 执行查询语句，返回表数据
			rs.next();// 移动指针到第一行
			int i = rs.getInt(1);// 获取房间数量
			rs.close();// 关闭结果集
			rs = stmt.executeQuery("SELECT HotelSysteam.Room.*, HotelSysteam.lodging.Date FROM HotelSysteam.Room LEFT OUTER JOIN HotelSysteam.lodging ON HotelSysteam.Room.ID = HotelSysteam.lodging.RoomID ORDER BY Room.ID;");// 执行查询语句，返回表数据
			// 检查是否有数据
			if(i == 0){
				JOptionPane.showMessageDialog(null, "查询房间列表失败，请联系管理员", "错误", JOptionPane.ERROR_MESSAGE);
				rs.close();// 关闭结果集
				return;
			}
			// 清空旧数据
			Main.panel2.removeAll();// 清空面板中的所有组件
			// 刷新面板
			Main.panel2.revalidate();// 刷新面板
			// 遍历结果集
			while (rs.next()) {
				// 读取房间ID
				String RoomID = rs.getString(1);
				// 读取单价
				String Price = rs.getString(2);
				// 读取入住日期
				String Date = rs.getString(3);
				// 房间状态等无需读取，因为房间状态是和入住日期有关的，如果返回NULL，则说明该房间未入住
				// 按钮上的文本内容为房间ID+单价+入住日期
				String text = "<html>门牌号:"+RoomID + "<br>价格:" + Price + "<br>" + Date+"</html>";
				// 创建按钮
				JButton btn = new JButton(text);
				// 如果入住日期不为NULL，将按钮颜色改为红色
				if (Date == null) {
					btn.setBackground(Color.WHITE);// 设置按钮颜色为白色
					if (firstEmptyRoomID == -1) {// 如果这是第一个空房间，则记录其ID
						firstEmptyRoomID = Integer.parseInt(RoomID);
					}
				} else {
					btn.setBackground(Color.RED);// 设置按钮颜色为红色
				}
				btn.setPreferredSize(new Dimension(80, 80));// 设置按钮大小
				// 添加按钮到面板
				Main.panel2.add(btn);
				// 监听按钮点击事件
				btn.addActionListener(e -> {
					// 检查权限是否为前台或超管
					if (Main.Permissions == 4 || Main.Permissions == 3) {
						// 调用前台模块的GetRoomInfo方法，传入房间ID
						Reception.GetRoomInfo(Integer.parseInt(RoomID));
						System.out.println("点击按钮切换到前台界面");
						Main.panel1.removeAll();// 清空面板
						Main.panel1.add(Reception.ReceptionPanel);// 添加前台管理界面
						Main.panel1.revalidate();// 重新布局
						Main.panel1.repaint();// 重新绘制
					}
					// 这个界面是任意权限都可以操作的界面，只有点开房间信息操作是需要权限的
				});
			}
			rs.close();// 关闭结果集
			stmt.close();// 关闭执行SQL的对象
			// 刷新面板
			Main.panel2.revalidate();// 刷新面板
			// 请求重绘
			Main.panel2.repaint();// 请求重绘
			// 调用Java内存GC操作
			System.gc();
		}catch(Exception e){// 如果查询失败，则显示错误
			JOptionPane.showMessageDialog(null, "查询房间列表失败，请联系管理员", "错误", JOptionPane.ERROR_MESSAGE);
			e.printStackTrace();
		}
	}
	public static void init()
	{
		System.out.println("正在初始化房间管理界面");
		// 创建面板
		HousingRegistration = new JPanel();
		GridBagLayout grid1 = new GridBagLayout();
		HousingRegistration.setLayout(grid1);
		// 添加房间号和单价输入框
		JTextField RoomNumber = new JTextField();
		JTextField Price = new JTextField();
		// 设置宽度
		RoomNumber.setColumns(5);
		Price.setColumns(5);
		// 添加(创建/删除/批量导入)按钮
		JButton Create = new JButton("创建");
		JButton Delete = new JButton("删除");
		JButton Import = new JButton("CSV批量导入");
		// 开始布局
		GridBagConstraints g1 = new GridBagConstraints();
		g1.gridx = 0; // 第几列
		g1.gridy = 0; // 第几行
		HousingRegistration.add(new JLabel("房间号:"), g1);
		g1 = new GridBagConstraints();
		g1.gridx = 1;
		g1.gridy = 0;
		g1.fill = GridBagConstraints.HORIZONTAL;
		HousingRegistration.add(RoomNumber, g1);
		g1 = new GridBagConstraints();
		g1.gridx = 0;
		g1.gridy = 1;
		HousingRegistration.add(new JLabel("单价:"), g1);
		g1.gridy = 1;
		g1.gridx = 1;
		g1.fill = GridBagConstraints.HORIZONTAL;
		HousingRegistration.add(Price, g1);
		g1 = new GridBagConstraints();
		g1.gridx = 0;
		g1.gridy = 2;
		HousingRegistration.add(Create, g1);
		g1 = new GridBagConstraints();
		g1.gridx = 1;
		g1.gridy = 2;
		HousingRegistration.add(Delete, g1);
		g1=new GridBagConstraints();
		g1.gridy = 3;
		g1.gridx = 0;
		// 宽度两列
		g1.gridwidth = 2;
		g1.fill = GridBagConstraints.HORIZONTAL;
		HousingRegistration.add(Import, g1);
		// 创建/删除按钮监听器
		Create.addActionListener(e -> {
			try {
				// 检查是否已经存在该房间号
				// SELECT `HotelSysteam`.`Room`.ID FROM `HotelSysteam`.`Room` WHERE ID = 101;
				Statement st = Main.conn.createStatement();// 创建语句对象
				String room = RoomNumber.getText();
				String price = Price.getText();
				ResultSet rs = st.executeQuery("SELECT `HotelSysteam`.`Room`.ID FROM `HotelSysteam`.`Room` WHERE ID = " + room); // 查询房间号是否存在
				if (rs.next()) {
					// 存在则提示,并询问是否修改
				int result = JOptionPane.showConfirmDialog(Main.window, "该房间号已存在，是否修改?", "提示", JOptionPane.YES_NO_OPTION);
					if (result == 0) {
						// 如果点击了是
						st.executeUpdate("UPDATE `HotelSysteam`.`Room` SET Price = '" + price + "' WHERE ID = " + room); // 更新价格
						// 刷新数据表
						UpdateRoomData();
						rs.close();// 释放资源
						return;
					} else {
						rs.close();// 释放资源
						return;// 直接返回，不做操作
					}
				}
				// 不存在则创建
				st.executeUpdate("INSERT INTO `HotelSysteam`.`Room` (`ID`, `Price`) VALUES ("+room+", "+price+");");
				// 刷新数据表
				UpdateRoomData();
				JOptionPane.showMessageDialog(Main.window, "创建成功", "提示", JOptionPane.INFORMATION_MESSAGE);
				rs.close();// 释放资源
				st.close();// 关闭语句对象
			} catch (SQLException e1) {
				JOptionPane.showMessageDialog(Main.window, "创建失败", "提示", JOptionPane.ERROR_MESSAGE);
				e1.printStackTrace();
			}
		});
		Delete.addActionListener(e -> {
			try {
				// 弹窗向用户二次确认
				int result = JOptionPane.showConfirmDialog(Main.window, "确定要删除房间号" + RoomNumber.getText() + "吗?", "提示", JOptionPane.YES_NO_OPTION);
				if (result != 0) {// 如果点击了否，则提前返回，不做操作
					return;
				}
				// 获取输入框中的内容
				String room = RoomNumber.getText();
				Statement st = Main.conn.createStatement();// 创建语句对象
				st.executeUpdate("DELETE FROM `HotelSysteam`.`Room` WHERE ID = " + room); // 删除房间号
				JOptionPane.showMessageDialog(Main.window, "删除成功", "提示", JOptionPane.INFORMATION_MESSAGE);
				st.close();// 关闭语句对象
				// 刷新数据表
				UpdateRoomData();
				
			} catch (SQLException e1) {
				JOptionPane.showMessageDialog(Main.window, "删除失败", "提示", JOptionPane.ERROR_MESSAGE);
			e1.printStackTrace();
			}
		});	
		Import.addActionListener(e -> {
			// 打开文件选择器，要求选择一个CSV文件
			// 第一列为房间号，第二列为单价
			JFileChooser file = new JFileChooser();
			file.setDialogTitle("选择文件一个CSV文件");
			int result = file.showOpenDialog(Main.window);
			if (result == 0) {
				File file1 = file.getSelectedFile();
				// 获取文件名，检查是否是CSV文件
				if (!file1.getName().endsWith(".csv")) {
					JOptionPane.showMessageDialog(Main.window, "请选择CSV文件", "提示", JOptionPane.INFORMATION_MESSAGE);
					return;
				}
				try {
					// 读取文件内容
					BufferedReader br = new BufferedReader(new FileReader(file1));// 创建文件读取对象
					Statement st = Main.conn.createStatement();// 创建语句对象
					String line;// 读取的每一行
					int errcount = 0;// 记录冲突的房间号数量
					int linecount = 0;// 获取文件行数
					byte table = 0;// 记录冲突解决方案，0为忽略冲突，1为全部导入，2为手动选择
				// 创建三个动态数组ArrayList，分别存储房间号(int)和单价(int)以及是否冲突(boolean)
					ArrayList<Integer> room = new ArrayList<>();// 存储房间号
					ArrayList<Integer> price = new ArrayList<>();// 存储单价
					ArrayList<Boolean> err = new ArrayList<>();// 存储是否冲突
					while ((line = br.readLine()) != null) {// 读取文件内容
						// 删除多余的空格
						line = line.trim();
						String[] data = line.split(",");// 获取一行数据，分割为数组
						int room1 = Integer.parseInt(data[0]);// 获取房间号
						int price1 = Integer.parseInt(data[1]);// 获取单价
						// 检测是否已经存在该房间号
						ResultSet rs = st.executeQuery("SELECT `HotelSysteam`.`Room`.ID FROM `HotelSysteam`.`Room` WHERE ID = " + room1); // 查询房间号是否存在
						if (rs.next()) {
							// 标为冲突
							err.add(true);
							room.add(room1);
							price.add(price1);
							errcount++;
						}
						else {
							// 不冲突则添加到ArrayList中
							err.add(false);
							room.add(room1);
							price.add(price1);
						}
						linecount++;// 记录行数
						rs.close();// 释放资源
					}
					// 询问用户如何处理冲突？可选项为：忽略冲突，全部导入，手动选择
					int result1 = JOptionPane.showConfirmDialog(Main.window, "准备导入"+linecount+"条数据\n存在冲突的房间号有" + errcount + "个，是否执行覆盖?", "提示", JOptionPane.YES_NO_OPTION);
					if (result1 == 0) {// 如果点击了是，则全部导入
					table = 1;
					} else {// 如果点击了否，则询问用户如何处理冲突
						int result2 = JOptionPane.showConfirmDialog(Main.window, "请选择处理方式\n选是为忽略冲突\n选否为手动模式", "提示", JOptionPane.YES_NO_OPTION);
						if (result2 == 0) {// 如果点击了是，则忽略冲突
							table = 0;
							} else {// 如果点击了否，则手动选择
								table = 2;
							}
					}
					// 开始导入数据
					for (int i = 0; i < linecount; i++) {
						// 检查是否存在冲突，如果没有则直接导入即可
							if (err.get(i) == false) {
							st.executeUpdate("INSERT INTO `HotelSysteam`.`Room` (`ID`, `Price`) VALUES (" + room.get(i) + ", " + price.get(i) + ");");// 插入数据
							} else {// 如果存在冲突，则根据用户选择处理方式
							switch (table) {
							case 0:// 如果选择忽略冲突，则直接跳过该条数据
								break;
							case 1:// 如果选择全部导入，则覆盖该条数据
								st.executeUpdate("UPDATE `HotelSysteam`.`Room` SET Price = " + price.get(i) + " WHERE ID = " + room.get(i));// 更新数据
								break;
							case 2:// 如果选择手动模式，则询问用户是否要导入该条数据
								{
									int result3 = JOptionPane.showConfirmDialog(Main.window, "是否要导入房间号" + room.get(i) + "的数据?", "提示", JOptionPane.YES_NO_OPTION);
									if (result3 == 0) {// 如果点击了是，则导入该条数据
										st.executeUpdate("UPDATE `HotelSysteam`.`Room` SET Price = " + price.get(i) + " WHERE ID = " + room.get(i));// 更新数据
									}
									else {// 如果点击了否，则不导入该条数据
										break;
									}
								}
							}
						}
					}
					st.close();// 关闭语句对象
					br.close();// 关闭文件读取对象
					// 刷新数据表
					UpdateRoomData();
					JOptionPane.showMessageDialog(Main.window, "导入成功", "提示", JOptionPane.INFORMATION_MESSAGE);
				} catch (SQLException e1) {// 捕获标准异常
					e1.printStackTrace();
					JOptionPane.showMessageDialog(Main.window, "导入失败", "提示", JOptionPane.ERROR_MESSAGE);
				} catch (FileNotFoundException e1) {// 捕获文件不存在异常
					JOptionPane.showMessageDialog(Main.window, "文件不存在", "提示", JOptionPane.ERROR_MESSAGE);
					e1.printStackTrace();
				} catch (IOException e1) {// 捕获IO异常
					JOptionPane.showMessageDialog(Main.window, "文件读取失败", "提示", JOptionPane.ERROR_MESSAGE);
					e1.printStackTrace();
				}
			}
			else
			{
				JOptionPane.showMessageDialog(Main.window, "没有选择文件，忽略执行", "提示", JOptionPane.INFORMATION_MESSAGE);
			}
		});
	}
}
